package dm

import (
	"fmt"
	"math/rand"
	"time"
)

/**
调度器
*/
func Select() {
	fmt.Println("select")
	ch1, ch2 := make(chan int, 10), make(chan int, 10) // 有值谁快先来谁

	//ch4 := make(chan int, 10000)

	go func() {
		for i := 0; i < 100000000; i++ {
			ch1 <- i
			time.Sleep(time.Millisecond)
		}
	}()
	go func() {
		for i := 100000000; i < 200000000; i++ {
			ch2 <- i
			time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond) // 随机1500毫秒
		}
	}()

	// 总控制10后结束
	tm := time.After(time.Second * 10) // 过了10秒回送个值过来

	// 每隔一段时间
	tick := time.Tick(time.Millisecond)

	// caches
	caches := make([]int, 0)

selected:
	for {
		var ch3 chan int // 没有空值直接跳过 默认nil channel非阻塞获取数据 <-chi3 空的消费不报错 但是初始化了不行 nil 不报错可执行
		if len(caches) > 0 {
			// 如果 caches 满了动态扩容 先取出所有的内容 进行复制创建空间更大的 或者调整供给策略慢点供给
			ch3 = make(chan int, 1)
			ch3 <- 1
		}
		select {
		case m := <-ch1: // 如果没有值直接就跳过case了
			fmt.Println("ch1")
			caches = append(caches, m)
		case m := <-ch2:
			fmt.Println("ch2")
			caches = append(caches, m)
		case s := <-ch3: // 解决收的速度和接的速度不统一可以定义个缓冲数组
			// 消费
			s = caches[0]
			caches = caches[1:]
			fmt.Println("ch3", s)
		case <-time.After(time.Nanosecond): // 每次case 接收的时间间隔 超过这个这个时间就会打印
			fmt.Println("超时", len(caches))
		case <-tick:
			fmt.Println("积压长度", len(caches), caches)
		case <-tm: // 到了10秒就发信号了 子协程虽然还在但是主协程执行完了就都完了
			fmt.Println("done select")
			break selected
		default:
			fmt.Println("defalut")
		}
		time.Sleep(time.Millisecond)
	}
}
